﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SlimDX;
using SlimDX.Direct3D11;

using Vxl.Utils;

namespace Vxl.Cameras
{
    public class BaseCamera
    {
        public Matrix View{
            get;
            protected set;    
        }

        public Matrix Projection
        {
            get;
            protected set;
        }

        protected Matrix Rotation
        {
            get;
            set;
        }

        public Vector3 Position
        {
            get;
            set;
        }

        public Vector3 LookAt
        {
            get;
            set;
        }

        protected Vector3 Up
        {
            get;
            set;
        }

        protected Vector3 Forward
        {
            get;
            set;
        }

        protected Vector3 Right
        {
            get;
            set;
        }

        protected Vector3 InitialUp
        {
            get;
            set;
        }

        protected Vector3 InitialForward
        {
            get;
            set;
        }

        protected Vector3 InitialRight
        {
            get;
            set;
        }
        
        protected Vector3 InitialPosition{
            get;
            set;
        }

        protected float totalYaw;
        protected float totalPitch;
        protected float totalRoll;
        protected float aspectRatio;

        public BaseCamera(Vector3 position, Vector3 lookAt)
        {
            Up = new Vector3(0,1,0);

            LookAt = lookAt;
            InitialPosition = position;
            Position = position;
            RecalculateCoordinates();

            View = Matrix.LookAtLH(Position, Position + Forward, Up);

            InitialRight = Right;
            InitialForward = Forward;
            InitialUp = Up;

            totalPitch = 0.0f;
            totalYaw = 0.0f;

            Rotation = Matrix.Identity;
            ResetProjection();
        }

        protected void RecalculateCoordinates()
        {
            Forward = Vector3.Normalize(LookAt - Position);

            Right = Vector3.Normalize(Vector3.Cross(Up, Forward));
            Up = Vector3.Normalize(Vector3.Cross(Forward, Right));
        }

        public virtual void Update(float dt) { }

        public void ResetProjection(){		
            Viewport vp = Globals.Device.ImmediateContext.Rasterizer.GetViewports()[0];

		    aspectRatio = ((float)vp.Width / (float)vp.Height);

		    float fov = (float)Math.PI / (2.0f * aspectRatio);

		    Projection = Matrix.PerspectiveFovLH(fov, aspectRatio, 0.1f, 1000.0f);
	    }
    }
}
